<script setup lang="ts">
import { shallowRef, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { useTresContext } from '@tresjs/core'
import * as THREE from 'three'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js'
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'
import { SAOPass } from 'three/examples/jsm/postprocessing/SAOPass.js'
import { BokehPass } from 'three/examples/jsm/postprocessing/BokehPass.js'
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'
import { OutputPass } from "three/examples/jsm/postprocessing/OutputPass.js"
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { deepClone } from '@/utils'

const chartEditStore = useChartEditStore()
const { scene, camera, renderer } = useTresContext()

// 获取 renderer 的尺寸
const rendererHeight = computed(() => {
  return renderer.value?.domElement?.height || 0
})
const rendererWidth = computed(() => {
  return renderer.value?.domElement?.width || 0
})

// 获取配置
const config = computed(() => {
  return chartEditStore.editCanvasConfig.postProcessing || {
    enabled: false,
    sao: { enabled: false, intensity: 1.0, diffusion: 80 },
    fxaa: { enabled: false },
    dof: { enabled: false },
    bloom: { enabled: false, strength: 2.5, radius: 0.6, threshold: 0.1 },
    selectiveBloom: { enabled: false, intensity: 2, radius: 0 },
    ssr: { enabled: false, intensity: 0.5, distance: 0.2 }
  }
})

// 后期处理相关变量
const composer = shallowRef<EffectComposer | null>(null)
const isInitialized = shallowRef(false)
const updateTimer = shallowRef<NodeJS.Timeout | null>(null)

const ensureRenderToScreen = () => {
  if (!composer.value) return
  composer.value.passes.forEach((pass, index) => {
    pass.renderToScreen = index === composer.value.passes.length - 1
  })
}

// 创建后期处理效果
const createPostProcessing = () => {
  console.log('开始创建后期效果...', {
    scene: !!scene.value,
    camera: !!camera.value,
    renderer: !!renderer.value,
    config: config.value
  })

  if (!scene.value || !camera.value || !renderer.value) {
    console.warn('后期效果创建失败：缺少必要的 Three.js 对象')
    return
  }

  try {
    // 清理现有的 composer
    if (composer.value) {
      composer.value.dispose()
    }
    
    // 创建新的 EffectComposer
    composer.value = new EffectComposer(renderer.value)
    console.log('EffectComposer 创建成功')
    
    // 添加渲染通道
    const renderPass = new RenderPass(scene.value, camera.value)
    composer.value.addPass(renderPass)
    
    const currentConfig = config.value
    
    // SAO 环境光遮蔽
    if (currentConfig.sao?.enabled) {
      const saoPass = new (SAOPass as any)(scene.value, camera.value, false, true)
      saoPass.params.output = SAOPass.OUTPUT.SAO
      saoPass.params.saoBias = 0.5
      saoPass.params.saoIntensity = currentConfig.sao.intensity
      saoPass.params.saoScale = currentConfig.sao.diffusion
      saoPass.params.saoKernelRadius = 100
      saoPass.params.saoMinResolution = 0
      saoPass.params.saoBlur = true
      saoPass.params.saoBlurRadius = 8
      saoPass.params.saoBlurStdDev = 4
      saoPass.params.saoBlurDepthCutoff = 0.01
      composer.value.addPass(saoPass)
    }
    
    // 全屏泛光
    if (currentConfig.bloom?.enabled) {
      const bloomPass = new UnrealBloomPass(
        new THREE.Vector2(rendererWidth.value, rendererHeight.value),
        currentConfig.bloom.strength,
        currentConfig.bloom.radius,
        currentConfig.bloom.threshold
      )
      composer.value.addPass(bloomPass)
    }
    
    // 指定辉光
    if (currentConfig.selectiveBloom?.enabled) {
      const selectiveBloomPass = new UnrealBloomPass(
        new THREE.Vector2(rendererWidth.value, rendererHeight.value),
        currentConfig.selectiveBloom.intensity,
        currentConfig.selectiveBloom.radius,
        0.99
      )
      composer.value.addPass(selectiveBloomPass)
    }

    // FXAA 抗锯齿
    if (currentConfig.fxaa?.enabled) {
      const fxaaPass = new ShaderPass(FXAAShader)
      composer.value.addPass(fxaaPass)
    }

    // 景深效果
    if (currentConfig.dof?.enabled) {
      const bokehPass = new BokehPass(scene.value, camera.value, {
        focus: 1.0,
        aperture: 0.025,
        maxblur: 0.01
      })
      composer.value.addPass(bokehPass)
    }

    // 添加 OutputPass 作为最后一个 pass
    const outputPass = new OutputPass()
    composer.value.addPass(outputPass)

    isInitialized.value = true
    console.log('后期效果初始化完成', {
      passesCount: composer.value.passes.length,
      enabled: config.value.enabled,
      passes: composer.value.passes.map(pass => pass.constructor.name)
    })
    
    ensureRenderToScreen()
  } catch (error) {
    console.error('后期效果初始化失败:', error)
  }
}

// 更新后期效果参数
const updatePostProcessing = () => {
  if (!composer.value || !isInitialized.value) return
  try {
    const currentConfig = config.value

    // 更新 SAO 参数
    if (currentConfig.sao?.enabled) {
      const saoPass = composer.value.passes.find(pass => pass instanceof SAOPass) as SAOPass
      if (saoPass) {
        saoPass.params.saoIntensity = currentConfig.sao.intensity
        saoPass.params.saoScale = currentConfig.sao.diffusion
      }
    }

    // 更新 Bloom 参数
    if (currentConfig.bloom?.enabled) {
      const bloomPass = composer.value.passes.find(pass => pass instanceof UnrealBloomPass) as UnrealBloomPass
      if (bloomPass) {
        bloomPass.strength = currentConfig.bloom.strength
        bloomPass.radius = currentConfig.bloom.radius
        bloomPass.threshold = currentConfig.bloom.threshold

      }
    }
    
    // 更新指定辉光参数
    if (currentConfig.selectiveBloom?.enabled) {
      const selectiveBloomPass = composer.value.passes.find(pass => 
        pass instanceof UnrealBloomPass && (pass as any).threshold === 0.99
      ) as UnrealBloomPass
      if (selectiveBloomPass) {
        selectiveBloomPass.strength = currentConfig.selectiveBloom.intensity
        selectiveBloomPass.radius = currentConfig.selectiveBloom.radius
      }
    }
    
    ensureRenderToScreen()
    console.log('后期效果参数更新完成',composer.value)
  } catch (error) {
    console.error('后期效果参数更新失败:', error)
  }
}

// 防抖更新
const debouncedUpdate = () => {
  if (updateTimer.value) {
    clearTimeout(updateTimer.value)
  }
  updateTimer.value = setTimeout(() => {
    updatePostProcessing()
  }, 100)
}

const disposeComposer = () => {
  if (composer.value) {
    composer.value.dispose()
    composer.value = null
  }
  isInitialized.value = false
}

const previousEnabled = shallowRef({
  sao: { ...config.value.sao },
  fxaa: { ...config.value.fxaa },
  dof: { ...config.value.dof },
  bloom: { ...config.value.bloom },
  enabled: config.value.enabled
})

// 监听配置变化
watch(
  () => config.value,
  (newConfig) => {
    const validatedConfig = newConfig
    const currentEnabled = validatedConfig.enabled
    const lastEnabled = previousEnabled.value

    if (currentEnabled !== lastEnabled.enabled) {
      if (currentEnabled) {
        nextTick(() => {
          createPostProcessing()
        })
      } else {
        disposeComposer()
      }
    } else {
      if (currentEnabled) {
        const bloom = lastEnabled.bloom.enabled != validatedConfig.bloom.enabled
        const sao = lastEnabled.sao.enabled != validatedConfig.sao.enabled
        const fxaa = lastEnabled.fxaa.enabled != validatedConfig.fxaa.enabled
        const dof = lastEnabled.dof.enabled != validatedConfig.dof.enabled
        
        // 检查 enabled 4个特效从 false 变为 true 时重新 createPostProcessing
        if (bloom || sao || fxaa || dof) {
          if ((bloom && validatedConfig.bloom.enabled) || (sao && validatedConfig.sao.enabled) || (fxaa && validatedConfig.fxaa.enabled) || (dof && validatedConfig.dof.enabled)) {
            nextTick(() => {
              createPostProcessing()
            })
          } else {
            disposeDComposer()
          }
        } else {
          // 检查参数值是否发生变化
          const bloomParamsChanged = JSON.stringify(lastEnabled.bloom) !== JSON.stringify(validatedConfig.bloom)
          const saoParamsChanged = JSON.stringify(lastEnabled.sao) !== JSON.stringify(validatedConfig.sao)
          
          if (bloomParamsChanged || saoParamsChanged) {
            debouncedUpdate()
          }
        }
      }
    }
    setTimeout(() => {
      previousEnabled.value = deepClone(newConfig)
    }, 100)
  },
  { deep: true }
)

// 效果关闭的话卸载效果
const disposeDComposer = () => {
  const { bloom, sao, fxaa, dof } = config.value
  if (composer.value) {
    // 卸载 UnrealBloomPass
    if (!bloom.enabled) {
      const index = composer.value.passes.findIndex(pass => pass instanceof UnrealBloomPass)
      if (index !== -1) {
        composer.value.passes[index].dispose && composer.value.passes[index].dispose()
        composer.value.passes.splice(index, 1)
      }
    }
    // 卸载 SAOPass
    if (!sao.enabled) {
      const index = composer.value.passes.findIndex(pass => pass instanceof SAOPass)
      if (index !== -1) {
        composer.value.passes[index].dispose && composer.value.passes[index].dispose()
        composer.value.passes.splice(index, 1)
      }
    }
    // 卸载 FXAA
    if (!fxaa.enabled) {
      const index = composer.value.passes.findIndex(pass => pass instanceof ShaderPass)
      if (index !== -1) {
        composer.value.passes[index].dispose && composer.value.passes[index].dispose()
        composer.value.passes.splice(index, 1)
      }
    }
    // 卸载 DOF
    if (!dof.enabled) {
      const index = composer.value.passes.findIndex(pass => pass instanceof BokehPass)
      if (index !== -1) {
        composer.value.passes[index].dispose && composer.value.passes[index].dispose()
        composer.value.passes.splice(index, 1)
      }
    }
  }
  ensureRenderToScreen()
}

// 渲染函数
const render = () => {
  if (composer.value && isInitialized.value && config.value.enabled) {
    try {
      composer.value.render()
      return true // 表示使用了后期效果渲染
    } catch (error) {
      console.error('后期效果渲染失败:', error)
    }
  }
  return false // 表示没有使用后期效果渲染
}

// 强制渲染函数（用于调试）
const forceRender = () => {
  if (composer.value && isInitialized.value) {
    composer.value.render()
  }
}

onMounted(() => {
  nextTick(() => {
    if (config.value.enabled) {
      createPostProcessing()
    }
  })
  
  // 启动自己的渲染循环作为备用方案
  startCustomRenderLoop()
})

// 自定义渲染循环
let customRenderLoopId = null
const startCustomRenderLoop = () => {
  const renderLoop = () => {
    if (composer.value && isInitialized.value && config.value.enabled) {
      try {
        composer.value.render()
      } catch (error) {
        console.error('自定义渲染循环错误:', error)
      }
    }
    customRenderLoopId = requestAnimationFrame(renderLoop)
  }
  customRenderLoopId = requestAnimationFrame(renderLoop)
  console.log('自定义渲染循环已启动')
}

onBeforeUnmount(() => {
  // 停止自定义渲染循环
  if (customRenderLoopId) {
    cancelAnimationFrame(customRenderLoopId)
    customRenderLoopId = null
  }
  
  if (composer.value) {
    composer.value.dispose()
  }
  if (updateTimer.value) {
    clearTimeout(updateTimer.value)
  }
})

// 暴露渲染函数给父组件
defineExpose({
  render,
  forceRender,
  composer: computed(() => composer.value),
  isInitialized: computed(() => isInitialized.value),
  config: computed(() => config.value),
  createPostProcessing,
  updatePostProcessing
})

// 全局调试函数
if (typeof window !== 'undefined') {
  (window as any).debugPostProcessing = {
    forceRender,
    getConfig: () => config.value,
    getComposer: () => composer.value,
    isInitialized: () => isInitialized.value,
    createPostProcessing,
    updatePostProcessing,
    // 强制启用后期效果进行测试
    // forceEnable: () => {
    //   console.log('强制启用后期效果进行测试')
    //   const testConfig = {
    //     enabled: true,
    //     bloom: { enabled: true, strength: 5.0, radius: 0.6, threshold: 0.1 },
    //     sao: { enabled: true, intensity: 1.0, diffusion: 80 },
    //     fxaa: { enabled: false },
    //     dof: { enabled: false },
    //     selectiveBloom: { enabled: false, intensity: 2, radius: 0 },
    //     ssr: { enabled: false, intensity: 0.5, distance: 0.2 }
    //   }
    //   chartEditStore.updatePostProcessingConfig(testConfig)
    //   setTimeout(() => {
    //     createPostProcessing()
    //   }, 100)
    // },
    // // 测试渲染状态
    // testStatus: () => {
    //   console.log('后期效果状态检查:', {
    //     composer: !!composer.value,
    //     initialized: isInitialized.value,
    //     enabled: config.value.enabled,
    //     passesCount: composer.value?.passes?.length || 0,
    //     passes: composer.value?.passes?.map(p => p.constructor.name) || [],
    //     customRenderLoop: !!customRenderLoopId
    //   })
    //   return {
    //     composer: !!composer.value,
    //     initialized: isInitialized.value,
    //     enabled: config.value.enabled,
    //     passesCount: composer.value?.passes?.length || 0,
    //     customRenderLoop: !!customRenderLoopId
    //   }
    // },
    // 手动触发渲染
    manualRender: () => {
      console.log('手动触发后期效果渲染')
      if (composer.value && isInitialized.value && config.value.enabled) {
        try {
          composer.value.render()
          console.log('手动渲染成功')
        } catch (error) {
          console.error('手动渲染失败:', error)
        }
      } else {
        console.log('无法手动渲染:', {
          composer: !!composer.value,
          initialized: isInitialized.value,
          enabled: config.value.enabled
        })
      }
    }
  }
}
</script>

<style scoped>
/* 后期效果组件样式 */
</style>